package com.theanh.RssActivity.ui.model;

import com.theanh.RssActivity.MainController;
import com.theanh.RssActivity.R;
import com.theanh.RssActivity.Store;
import com.theanh.RssActivity.db.DbAdapter;
import com.theanh.RssActivity.entity.Channel;
import com.theanh.RssActivity.entity.Item;
import com.theanh.RssActivity.updater.ChannelUpdater;
import com.theanh.RssActivity.util.Constants;
import com.theanh.RssActivity.util.DbUtils;
import com.theanh.RssActivity.util.DialogUtils;
import com.theanh.RssActivity.util.FileUtils;
import com.theanh.RssActivity.util.ProgressBar;
import com.theanh.RssActivity.util.Utils;

import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ChannelModel {
	protected static final int BEGIN_UPDATE_CHANNEL_MESSAGE = 0;
	protected static final int END_UPDATE_CHANNEL_MESSAGE = 1;
	protected static final int ERROR_UPDATE_CHANNEL_MESSAGE = 2;
	private static final String TAG = "ChannelModel";

	ProgressBar icon;
	TextView name;
	TextView numberItem;
	LinearLayout mainView;

	public Channel channel;
	private ChannelUpdater updater = null;

	public static ChannelModel createModel(View view) {
		ChannelModel model = new ChannelModel();
		model.icon = (ProgressBar) view.findViewById(R.id.channelIconImageView);
		model.icon.setImageResource(R.drawable.progressbar_3);
		model.icon.setOnClickListener(model.updateChannelOnClick);

		model.name = (TextView) view.findViewById(R.id.channelNameTextView);
		model.name.setTypeface(Typeface.DEFAULT_BOLD);
		model.name.setTextColor(android.graphics.Color.WHITE);

		model.numberItem = (TextView) view
				.findViewById(R.id.channelNumberItemTextView);
		model.mainView = (LinearLayout) view
				.findViewById(R.id.rowChannelLinearLayout);
		// model.mainView.setOnClickListener(model.openLinkOnClick);
		model.mainView.setOnClickListener(model.openChannelOnClick);
		model.mainView.setOnFocusChangeListener(model.focusChange);
		model.mainView.setFocusable(true);

		return model;
	}
	
	public void startUpdate(){
		if (updater == null || !updater.isAlive() || updater.getState() == Thread.State.TERMINATED) {
			updater = new ChannelUpdater(
					ChannelModel.this.channel);
			updater.setModel(ChannelModel.this);
			updater.setPriority(Thread.MIN_PRIORITY);
			updater.setDaemon(true);
			
			ChannelModel.this.channel.setUpdating(true);
			try {
				updater.start();
			} catch(IllegalThreadStateException ex){
				Log.e(TAG, ex.toString());
			}
		}
	}
	
	public void stopUpdate(){
		if (updater != null && updater.isAlive()){
			try{
				updater.interrupt();
				ChannelModel.this.channel.setUpdating(false);
				endUpdate();
				updater = null;
			} catch(SecurityException ex){
				Log.e(TAG, ex.toString());
			}
		}
	}

	private OnClickListener updateChannelOnClick = new OnClickListener() {
		public void onClick(View view) {
			Store.hasChannelFocus = true;
			Store.channelModelSelected = ChannelModel.this;
			
			// check validate url
			
			if (!ChannelModel.this.channel.isUpdating()) {
				startUpdate();
			} else {
				stopUpdate();
			}
			// check validate url
		}
	};

	private OnFocusChangeListener focusChange = new View.OnFocusChangeListener() {
		public void onFocusChange(View v, boolean hasFocus) {
			if (hasFocus) {
				Store.hasChannelFocus = true;
				Store.channelModelSelected = ChannelModel.this;
			} else {
				Store.hasChannelFocus = false;
			}
		}
	};
	private OnClickListener openChannelOnClick = new OnClickListener() {
		public void onClick(View view) {
			Store.channelModelSelected = ChannelModel.this;

			// Auto update channel
			long numberItem = 0;
			DbAdapter dbAdapter = null;
			try {
				dbAdapter = DbUtils.createAndOpenDbAdapter();
				numberItem = dbAdapter
						.getNumberItem(Store.channelModelSelected.channel);
			} catch (Exception ex) {
				Log.e(TAG, ex.toString());
			} finally {
				if (dbAdapter != null) {
					DbUtils.closeDbAdapter(dbAdapter);
				}
			}
			if (Store.setting.isAutoUpdate() || numberItem == 0) {
				ChannelUpdater updater = new ChannelUpdater(
						ChannelModel.this.channel);
				updater.setModel(ChannelModel.this);
				updater.start();
			}
			// Open list item screen
			MainController.showListItemScreen(channel);
			if (Store.setting.isAutoUpdate() || numberItem ==0 ){
				ChannelUpdater updater = new ChannelUpdater(
						ChannelModel.this.channel);
				updater.setModel(ChannelModel.this);
				updater.start();
			}
			
			// Open list item screen
			MainController.showListItemScreen(channel);
		}
	};

	public void bind(Channel channel) {
		this.channel = channel;
		name.setText(channel.getName());

		updateNumberItem();
		
		showLogo();
	}

	public void updateNumberItem() {
		// Open DB
		DbAdapter dbAdapter = DbUtils.createAndOpenDbAdapter();
		long numberReaded = dbAdapter.getNumberItem(channel);
		long numberUnRead = dbAdapter.getNumberItemUnRead(channel);
		// Close DB
		DbUtils.closeDbAdapter(dbAdapter);

		numberItem.setText(numberUnRead + "/" + numberReaded);
	}

	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case BEGIN_UPDATE_CHANNEL_MESSAGE:
				// Change icon
				// ChannelModel.this.icon.setImageResource(R.drawable.rss1);
				ChannelModel.this.icon.images = new int[] {
						R.drawable.progressbar_1, R.drawable.progressbar_2,
						R.drawable.progressbar_3 };
				ChannelModel.this.icon.start();

				// Update status
				ChannelModel.this.numberItem.setText(R.string.updating_text);

				Log.i(TAG, "BEGIN_UPDATE_CHANNEL_MESSAGE");
				break;
			case END_UPDATE_CHANNEL_MESSAGE:
				// Stop animation
				ChannelModel.this.icon.stop();
				
				showLogo();
				
				ChannelModel.this.channel.setUpdating(false);
				// Updata status
				updateNumberItem();
				Log.i(TAG, "END_UPDATE_CHANNEL_MESSAGE");
				break;
			case ERROR_UPDATE_CHANNEL_MESSAGE:
				showLogo();
				DialogUtils.showDialogError(ChannelModel.this.mainView.getContext(), errorMessage);
				
				break;
			}
			super.handleMessage(msg);
		}
	};

	private void showLogo(){
		// Change icon
		Bitmap logo = null;
		if (channel.getLogoUrl()!= null && channel.getLogoUrl().length() !=0){
			logo = FileUtils.loadImage(Constants.CHANNEL_LOGO_PREFIX + channel.getID());
			ChannelModel.this.icon.setImageBitmap(logo);
		}
		if (logo == null)
			ChannelModel.this.icon
					.setImageResource(R.drawable.progressbar_3);
	}
	
	protected void sendMessage(int identifier) {
		Message message = new Message();
		message.what = identifier;

		// send data to update GUI
		handler.sendMessage(message);
	}

	public void beginUpdate() {
		sendMessage(BEGIN_UPDATE_CHANNEL_MESSAGE);
	}

	public void endUpdate() {
		sendMessage(END_UPDATE_CHANNEL_MESSAGE);
	}

	private String errorMessage = null;
	public void errorUpdate(String msg){
		errorMessage = msg;
		sendMessage(ERROR_UPDATE_CHANNEL_MESSAGE);
	}

	public void update() {
		name.setText(channel.getName());
	}
}
